package com.vcc.service.impl;


import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.vcc.core.exception.NotFoundException;
import com.vcc.core.exception.ProgramException;
import com.vcc.core.util.EncryptUtil;
import com.vcc.core.util.RegexUtil;
import com.vcc.data.entity.BossUser;
import com.vcc.data.mapper.BossUserMapper;
import com.vcc.service.boss.request.bossUser.BossRegisterRequest;
import com.vcc.service.sa.BossUserUtil;
import com.vcc.service.service.BossUserService;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

import static com.vcc.data.entity.table.BossUserTableDef.BOSS_USER;

@Service
public class BossUserServiceImpl extends ServiceImpl<BossUserMapper, BossUser> implements BossUserService {


    @Override
    public BossUser login(String account) {
        return queryChain().eq(BossUser::getEmail, (account)).oneOpt().orElseThrow(() -> new NotFoundException("没有当前账号，无法登录"));
    }

    @Override
    public BossUser login(String account, String password) {
        return queryChain()
                .eq(BossUser::getEmail, account)
                .oneOpt().orElseThrow(() -> new NotFoundException("登录失败，请检查登录账号密码"));

    }

    @Override
    public BossUser register(BossRegisterRequest bossRegisterRequest, Long opUserId) {
        if (queryChain().eq(BossUser::getAccount, bossRegisterRequest.getAccount()).exists()) {
            throw new ProgramException("当前账号已存在，无法注册");
        }
        if (queryChain().eq(BossUser::getEmail, bossRegisterRequest.getEmail()).exists()) {
            throw new ProgramException("当前邮箱已存在，无法注册");
        }
        BossUser bossUser = new BossUser();
        bossUser.setUsername(bossRegisterRequest.getUsername());
        bossUser.setAccount(bossRegisterRequest.getAccount());
        bossUser.setEmail(bossRegisterRequest.getEmail());
        bossUser.setStatus(0);
        bossUser.setRegisterUserId(opUserId);
        bossUser.setSalt(IdUtil.randomUUID());
        bossUser.setPassword(EncryptUtil.encryptValue(bossRegisterRequest.getPassword(), bossUser.getSalt()));
        bossUser.setParentId(BossUserUtil.getId());
        bossUser.setHasBindGoogle(false);
        String invitationCode;
        do {
            invitationCode = RandomUtil.randomNumbers(6);
        } while (existByInvitationCode(invitationCode));
        bossUser.setInvitationCode(invitationCode);
        save(bossUser);
        return bossUser;
    }

    @Override
    public Page<BossUser> paging(
            Page<BossUser> pageable,
            Long targetId,
            String username,
            String email,
            String account,
            String invitationCode,
            Integer status) {
        QueryChain<BossUser> queryChain = queryChain();
        //去User 统计注册用户数
        queryChain.select(BOSS_USER.ALL_COLUMNS);
        queryChain.select(
                " (select count(id) from vcc_user u where u.be_long_to_dealer = vcc_boss_user.id) as registerCount "
        );
        if (RegexUtil.checkObjectIsNotNull(status)) {
            queryChain.eq(BossUser::getStatus, status);
        }
        if (RegexUtil.checkObjectIsNotNull(targetId)) {
            queryChain.eq(BossUser::getId, targetId);
        }
        if (RegexUtil.checkObjectIsNotNull(username)) {
            queryChain.like(BossUser::getUsername, username);
        }
        if (RegexUtil.checkObjectIsNotNull(email)) {
            queryChain.like(BossUser::getEmail, email);
        }
        if (RegexUtil.checkObjectIsNotNull(account)) {
            queryChain.like(BossUser::getAccount, account);
        }
        if (RegexUtil.checkObjectIsNotNull(invitationCode)) {
            queryChain.eq(BossUser::getInvitationCode, invitationCode);
        }
        if (!BossUserUtil.hasAllData()) {
            queryChain.where(BOSS_USER.ID.eq(BossUserUtil.getId()).or(BOSS_USER.PARENT_ID.eq(BossUserUtil.getId())));
        }
        queryChain.orderBy(BossUser::getCreateDate, false);
        return queryChain.page(pageable);
    }

    @Override
    public String getAccountById(Long id) {
        return mapper.findAccountById(id);
    }

    @Override
    public String getUserNameById(Long id) {
        return mapper.findUserNameById(id);
    }

    @Override
    public Boolean updateStatusById(Long userId, Integer status) {
        return updateChain().eq(BossUser::getId, userId).set(BossUser::getStatus, status).update();
    }

    @Override
    public boolean updatePasswordById(Long id, String password) {
        return updateChain().eq(BossUser::getId, id).set(BossUser::getPassword, (password)).update();
    }

    @Override
    public boolean updateAccountById(Long id, String account) {
        if (queryChain().eq(BossUser::getAccount, account).exists()) {
            throw new ProgramException("当前账号已存在，无法修改");
        }
        return updateChain().eq(BossUser::getId, id).set(BossUser::getAccount, account).update();
    }

    @Override
    public boolean updateEmailById(Long id, String email) {
        if (queryChain().eq(BossUser::getEmail, email).exists()) {
            throw new ProgramException("当前邮箱已存在，无法修改");
        }
        return updateChain().eq(BossUser::getId, id).set(BossUser::getEmail, email).update();
    }

    @Override
    public boolean updateUsernameById(Long id, String username) {
        return updateChain().eq(BossUser::getId, id).set(BossUser::getUsername, username).update();
    }

    @Override
    public BossUser getByEmail(String email) {
        return queryChain().eq(BossUser::getEmail, email).oneOpt().orElseThrow(() -> new NotFoundException("账户信息错误"));
    }

    @Override
    public Boolean existsByEmail(String email) {
        QueryChain<BossUser> queryChain = queryChain();
        queryChain.eq(BossUser::getEmail, email);
        return queryChain.exists();
    }

    @Override
    public Boolean bindGoogle(Long id, String googleSecret) {
        return updateChain()
                .eq(BossUser::getId, id)
                .set(BossUser::getHasBindGoogle, true)
                .set(BossUser::getGoogleSecret, googleSecret)
                .set(BossUser::getGoogleBindTime, new Date())
                .update();
    }

    @Override
    public Long getByInvitationCode(String invitationCode) {
        QueryChain<BossUser> queryChain = queryChain().select(BOSS_USER.ID);
        queryChain.eq(BossUser::getInvitationCode, invitationCode);
        return queryChain.oneAsOpt(Long.class).orElseThrow(() -> new ProgramException("没有这个邀请码"));
    }

    @Override
    public Boolean existByInvitationCode(String invitationCode) {
        QueryChain<BossUser> queryChain = queryChain();
        queryChain.eq(BossUser::getInvitationCode, invitationCode);
        return queryChain.exists();
    }

    @Override
    public Boolean existsById(Long id) {
        return queryChain().eq(BossUser::getId, id).exists();
    }

    @Override
    public Boolean clearGoogle(Long id) {
        return updateChain()
                .eq(BossUser::getId, id)
                .set(BossUser::getHasBindGoogle, false)
                .set(BossUser::getGoogleSecret, null)
                .set(BossUser::getGoogleBindTime, null)
                .update();
    }

    @Override
    public List<BossUser> listByEmailLike(String email) {
        if (!BossUserUtil.hasAllData()) {
            return queryChain()
                    .where(BOSS_USER.ID.eq(BossUserUtil.getId()).or(BOSS_USER.PARENT_ID.eq(BossUserUtil.getId())))
                    .like(BossUser::getEmail, email)
                    .list();
        }
        return queryChain().like(BossUser::getEmail, email).list();
    }


    @Override
    public Long getParentIdById(Long id) {
        QueryChain<BossUser> queryChain = queryChain().select(BOSS_USER.PARENT_ID).eq(BossUser::getId, id);
        return queryChain.oneAsOpt(Long.class).orElse(0L);
    }

    @Override
    public Integer getStatusById(Long id) {
        QueryChain<BossUser> queryChain = queryChain().select(BOSS_USER.STATUS).eq(BossUser::getId, id);
        return queryChain.oneAsOpt(Integer.class).orElse(0);
    }

    @Override
    public Boolean updateAdminRemarkById(Long id, String adminRemark) {
        return updateChain().eq(BossUser::getId, id).set(BossUser::getAdminRemark, adminRemark).update();
    }
}
